package com.sayice.gomoku.dao.impl;

import com.sayice.gomoku.utils.JdbcUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.math.BigInteger;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.function.Consumer;

/**
 * 数据库操作
 */
public abstract class BaseDao {
    
    // 使用 dbutils 操作数据库
    
    private final QueryRunner queryRunner = new QueryRunner();
    
    /**
     * 执行：Insert\Update\Delete 语句
     *
     * @param setId 自增主键对应属性的 set 方法，不需要获取自增主键时传入 null
     * @param sql  执行的 sql 语句
     * @param args sql 对应的参数值
     * @return 返回 sql 语句影响的行数
     */
    public int update(Consumer<Integer> setId, String sql, Object... args) {
        Connection conn = JdbcUtils.getConnection();
        try {
            int count = queryRunner.update(conn, sql, args);
            if (setId != null) {
                BigInteger id = queryRunner.query(conn,"select @@identity", new ScalarHandler<>(1));
                setId.accept(id.intValue());
            }
            return count;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 执行返回一行的 sql 查询语句
     *
     * @param <T>  返回的类型的泛型
     * @param type 返回的对象类型
     * @param sql  执行的 sql 语句
     * @param args sql 对应的参数值
     * @return 返回 JavaBean 对象
     */
    public <T> T queryForOne(Class<T> type, String sql, Object... args) {
        Connection conn = JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn, sql, new BeanHandler<>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 执行返回多行的 sql 查询语句
     *
     * @param <T>  返回的类型的泛型
     * @param type 返回的对象类型
     * @param sql  执行的 sql 语句
     * @param args sql 对应的参数值
     * @return 返回 JavaBean 对象集合
     */
    public <T> List<T> queryForList(Class<T> type, String sql, Object... args) {
        Connection conn = JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn, sql, new BeanListHandler<>(type), args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    /**
     * 执行返回一行一列的 sql 查询语句
     *
     * @param sql  执行的sql语句
     * @param args sql对应的参数值
     * @return 返回查询结果对象
     */
    public Object queryForSingleValue(String sql, Object... args) {
        Connection conn = JdbcUtils.getConnection();
        try {
            return queryRunner.query(conn, sql, new ScalarHandler<>(), args);
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
}
